#!/usr/bin/env python3
"""
智能测试用例生成系统 - Web应用

本模块提供了基于Flask框架的Web应用，实现了智能测试用例生成系统的所有核心功能。
系统通过Web界面为用户提供编程题目分析、测试用例生成、管理和导出等完整服务。

主要功能：
- 编程题目智能分析：使用规则引擎和机器学习模型分析编程问题
- 测试用例自动生成：基于分析结果生成多种类型的测试用例
- 用户认证管理：支持用户登录、权限控制和会话管理
- 测试用例管理：提供测试用例的增删改查功能
- 数据导出功能：支持多种格式的结果导出（JSON、文本、Python、Markdown）
- 批量处理：支持批量分析和导出功能
- 历史记录：保存和管理分析历史
- 统计信息：提供系统使用统计和分析报告

技术特点：
- Flask Web框架
- 使用Flask-Session进行用户状态管理
- 提供RESTful API接口
- 支持多种格式的文件导出和下载
- 集成MySQL数据库
- 机器学习集成：支持ML模型增强的分析功能

系统架构：
- 前端：HTML + CSS + JavaScript
- 后端：Flask + Python
- 数据库：MySQL
- 机器学习：scikit-learn + joblib
- 规则引擎：JSON规则 + 正则表达式

API接口：
- 用户认证：/api/login, /api/logout, /api/check-login
- 题目分析：/api/analyze
- 数据导出：/api/export, /batch_export
- 测试用例管理：/api/test-cases, /api/problems
- 历史记录：/history, /clear_history
- 统计信息：/api/statistics, /api/samples

"""

# ==================== 导入和配置 ====================

import sys
import os
from datetime import datetime

# 添加src目录到Python路径
# 确保可以导入src目录下的模块
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'src')))

# Flask相关导入
from flask import Flask, render_template, request, jsonify, send_file, session
import json
import zipfile
import io

# 导入核心模块
from main_analyzer import ProgrammingProblemAnalyzer
from test_case_manager import test_case_db, TestCase, TestCaseSet
from user_manager import user_db, User

# ==================== Flask应用配置 ====================

# 创建Flask应用实例
app = Flask(__name__)

# 配置session密钥
# 在生产环境中应该使用更安全的密钥
app.secret_key = 'your-secret-key-change-in-production'

# ==================== 分析器初始化 ====================

# 初始化分析器
# 检查是否有训练好的ML模型
ml_model_path = None
if os.path.exists("models"):
    # 查找最佳模型文件
    for file in os.listdir("models"):
        if file.startswith("best_model_") and file.endswith(".joblib"):
            ml_model_path = os.path.join("models", file)
            break

# 配置分析器参数
config = {
    'enable_ml_enhancement': ml_model_path is not None,  # 是否启用ML增强
    'ml_model_path': ml_model_path,                       # ML模型路径
    'verbose': False                                      # 是否显示详细日志
}

# 创建分析器实例
analyzer = ProgrammingProblemAnalyzer(config)

# ==================== 工具函数 ====================

def _format_result_as_text(result):
    """
    将分析结果格式化为纯文本格式
    
    将编程题目分析结果转换为易读的文本格式，包含问题类型、
    输入输出格式、约束条件和测试用例详情。
    
    参数:
        result (dict): 分析结果字典，包含success、analysis_result等字段
        
    返回:
        str: 格式化后的文本字符串
        
    格式内容:
        - 问题类型
        - 输入格式描述
        - 输出格式描述
        - 约束条件数量
        - 测试用例详情（描述、输入、预期输出、类型）
        
    使用示例:
        result = analyzer.analyze_problem("计算两个数的和")
        text = _format_result_as_text(result)
        print(text)
    """
    lines = []
    lines.append("编程题目分析结果")
    lines.append("=" * 50)
    
    if result.get('success'):
        analysis = result.get('analysis_result', {})
        test_cases = analysis.get('test_cases', [])
        
        # 添加基本信息
        lines.append(f"问题类型: {analysis.get('operation', 'unknown')}")
        lines.append(f"输入格式: {analysis.get('input_format', {}).get('description', 'unknown')}")
        lines.append(f"输出格式: {analysis.get('output_format', {}).get('description', 'unknown')}")
        lines.append(f"约束条件: {len(analysis.get('constraints', []))} 个")
        lines.append(f"测试用例: {len(test_cases)} 个")
        lines.append("")
        
        # 添加测试用例详情
        lines.append("测试用例详情:")
        for i, case in enumerate(test_cases, 1):
            lines.append(f"  测试用例 {i}: {case.get('description', '')}")
            lines.append(f"    输入: {case.get('input')}")
            lines.append(f"    预期输出: {case.get('expected_output')}")
            lines.append(f"    类型: {case.get('type', 'unknown')}")
            lines.append("")
    else:
        # 处理分析失败的情况
        lines.append(f"分析失败: {result.get('error', 'unknown error')}")
    
    return "\n".join(lines)

def _format_result_as_python(result):
    """
    将分析结果格式化为Python代码格式
    
    将编程题目分析结果转换为可执行的Python代码格式，
    生成测试用例的Python数据结构，便于在Python环境中使用。
    
    参数:
        result (dict): 分析结果字典，包含success、analysis_result等字段
        
    返回:
        str: 格式化后的Python代码字符串
        
    生成内容:
        - 文件头注释和时间戳
        - 问题类型、输入输出格式注释
        - test_cases列表，包含所有测试用例的字典结构
        
    使用示例:
        result = analyzer.analyze_problem("计算两个数的和")
        python_code = _format_result_as_python(result)
        with open("test_cases.py", "w") as f:
            f.write(python_code)
    """
    lines = []
    lines.append("# 编程题目分析结果")
    lines.append(f"# 生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    lines.append("")
    
    if result.get('success'):
        analysis = result.get('analysis_result', {})
        test_cases = analysis.get('test_cases', [])
        
        # 添加问题信息注释
        lines.append(f"# 问题类型: {analysis.get('operation', 'unknown')}")
        lines.append(f"# 输入格式: {analysis.get('input_format', {}).get('description', 'unknown')}")
        lines.append(f"# 输出格式: {analysis.get('output_format', {}).get('description', 'unknown')}")
        lines.append("")
        
        # 生成测试用例列表
        lines.append("test_cases = [")
        for i, case in enumerate(test_cases):
            lines.append(f"    {{")
            lines.append(f"        'id': {i + 1},")
            lines.append(f"        'description': '{case.get('description', '')}',")
            lines.append(f"        'input': {repr(case.get('input'))},")
            lines.append(f"        'expected_output': {repr(case.get('expected_output'))},")
            lines.append(f"        'type': '{case.get('type', 'unknown')}'")
            lines.append(f"    }}{',' if i < len(test_cases) - 1 else ''}")
        lines.append("]")
    else:
        # 处理分析失败的情况
        lines.append(f"# 分析失败: {result.get('error', 'unknown error')}")
    
    return "\n".join(lines)

def _format_result_as_markdown(result):
    """
    将分析结果格式化为Markdown格式
    
    将编程题目分析结果转换为Markdown格式，便于在文档、
    博客或GitHub等平台中展示和分享。
    
    参数:
        result (dict): 分析结果字典，包含success、analysis_result等字段
        
    返回:
        str: 格式化后的Markdown字符串
        
    生成内容:
        - 标题和时间戳
        - 问题类型、输入输出格式、约束条件
        - 测试用例列表，使用Markdown表格格式
        
    使用示例:
        result = analyzer.analyze_problem("计算两个数的和")
        markdown = _format_result_as_markdown(result)
        with open("analysis_result.md", "w") as f:
            f.write(markdown)
    """
    lines = []
    lines.append("# 编程题目分析结果")
    lines.append(f"**生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    lines.append("")
    
    if result.get('success'):
        analysis = result.get('analysis_result', {})
        test_cases = analysis.get('test_cases', [])
        
        # 添加基本信息
        lines.append(f"## 问题类型\n{analysis.get('operation', 'unknown')}")
        lines.append(f"## 输入格式\n{analysis.get('input_format', {}).get('description', 'unknown')}")
        lines.append(f"## 输出格式\n{analysis.get('output_format', {}).get('description', 'unknown')}")
        lines.append(f"## 约束条件\n{len(analysis.get('constraints', []))} 个")
        lines.append(f"## 测试用例 ({len(test_cases)}个)")
        lines.append("")
        
        # 添加测试用例详情
        for i, case in enumerate(test_cases, 1):
            lines.append(f"### 测试用例 {i}")
            lines.append(f"- **描述**: {case.get('description', '')}")
            lines.append(f"- **输入**: `{case.get('input')}`")
            lines.append(f"- **预期输出**: `{case.get('expected_output')}`")
            lines.append(f"- **类型**: {case.get('type', 'unknown')}")
            lines.append("")
    else:
        # 处理分析失败的情况
        lines.append(f"## 分析失败\n{result.get('error', 'unknown error')}")
    
    return "\n".join(lines)

# ==================== 页面路由 ====================

@app.route('/')
def index():
    """
    主页路由
    
    返回系统的主页面，提供编程题目分析和测试用例生成的主要功能入口。
    
    返回:
        str: 渲染后的index.html模板
        
    页面功能:
        - 编程题目输入界面
        - 分析参数配置
        - 结果展示区域
        - 导出功能按钮
        
    访问方式:
        GET http://localhost:5000/
    """
    return render_template('index.html')

@app.route('/login')
def login():
    """
    登录页面路由
    
    返回用户登录页面，提供用户名和密码输入界面。
    
    返回:
        str: 渲染后的login.html模板
        
    页面功能:
        - 用户名输入框
        - 密码输入框
        - 登录按钮
        - 错误信息显示
        
    访问方式:
        GET http://localhost:5000/login
    """
    return render_template('login.html')

# ==================== API接口 ====================

@app.route('/api/login', methods=['POST'])
def api_login():
    """
    用户登录API接口
    
    处理用户登录请求，验证用户名和密码，设置会话状态。
    
    请求方法:
        POST
        
    请求参数:
        JSON格式:
        {
            "username": "用户名",
            "password": "密码"
        }
        
    返回格式:
        JSON格式:
        {
            "success": true/false,
            "message": "消息",
            "user": {
                "id": 用户ID,
                "username": "用户名",
                "real_name": "真实姓名",
                "role": "角色"
            },
            "redirect": "重定向URL"
        }
        
    异常处理:
        - 用户名或密码为空
        - 用户名或密码错误
        - 系统异常
        
    访问方式:
        POST http://localhost:5000/api/login
    """
    try:
        # 获取请求数据
        data = request.get_json()
        username = data.get('username', '').strip()
        password = data.get('password', '')
        
        # 验证输入参数
        if not username or not password:
            return jsonify({
                'success': False,
                'message': '用户名和密码不能为空'
            })
        
        # 验证用户凭据
        user = user_db.authenticate_user(username, password)
        if user:
            # 设置会话信息
            session['user_id'] = user.id
            session['username'] = user.username
            session['real_name'] = user.real_name
            session['role'] = user.role
            session['is_logged_in'] = True
            
            return jsonify({
                'success': True,
                'message': '登录成功',
                'user': {
                    'id': user.id,
                    'username': user.username,
                    'real_name': user.real_name,
                    'role': user.role
                },
                'redirect': '/'
            })
        else:
            return jsonify({
                'success': False,
                'message': '用户名或密码错误'
            })
    except Exception as e:
        return jsonify({
            'success': False,
            'message': f'登录失败: {str(e)}'
        })

@app.route('/api/logout', methods=['POST'])
def api_logout():
    """
    用户登出API接口
    
    处理用户登出请求，清除会话状态并重定向到主页。
    
    请求方法:
        POST
        
    返回格式:
        JSON格式:
        {
            "success": true,
            "message": "已退出登录",
            "redirect": "/"
        }
        
    功能:
        - 清除所有会话信息
        - 重定向到主页
        
    访问方式:
        POST http://localhost:5000/api/logout
    """
    # 清除会话信息
    session.clear()
    return jsonify({
        'success': True,
        'message': '已退出登录',
        'redirect': '/'
    })

@app.route('/api/check-login', methods=['GET'])
def api_check_login():
    """
    检查登录状态API接口
    
    检查当前用户的登录状态，返回用户信息。
    
    请求方法:
        GET
        
    返回格式:
        JSON格式:
        {
            "success": true/false,
            "is_logged_in": true/false,
            "user": {
                "id": 用户ID,
                "username": "用户名",
                "real_name": "真实姓名",
                "role": "角色"
            }
        }
        
    异常处理:
        - 会话异常
        - 系统错误
        
    访问方式:
        GET http://localhost:5000/api/check-login
    """
    try:
        # 检查会话中的登录状态
        is_logged_in = session.get('is_logged_in', False)
        user_info = None
        
        if is_logged_in:
            # 构建用户信息
            user_info = {
                'id': session.get('user_id'),
                'username': session.get('username'),
                'real_name': session.get('real_name'),
                'role': session.get('role')
            }
        
        return jsonify({
            'success': True,
            'is_logged_in': is_logged_in,
            'user': user_info
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'is_logged_in': False,
            'error': str(e)
        })

@app.route('/new-test-case')
def new_test_case():
    """
    新建测试用例页面路由
    
    返回测试用例创建页面，提供手动创建和编辑测试用例的功能。
    
    返回:
        str: 渲染后的new_test_case.html模板
        
    页面功能:
        - 测试用例信息输入
        - 问题描述编辑
        - 输入输出格式设置
        - 测试用例保存
        
    访问方式:
        GET http://localhost:5000/new-test-case
    """
    return render_template('new_test_case.html')

@app.route('/teacher')
def teacher_management():
    """
    教师管理页面路由
    
    返回教师专用的管理页面，提供测试用例管理、问题管理等功能。
    
    返回:
        str: 渲染后的teacher.html模板
        
    页面功能:
        - 测试用例列表查看
        - 问题管理
        - 批量操作
        - 数据统计
        
    访问方式:
        GET http://localhost:5000/teacher
    """
    return render_template('teacher.html')

@app.route('/analyze', methods=['POST'])
@app.route('/api/analyze', methods=['POST'])
def analyze():
    """
    编程题目分析API接口
    
    这是系统的核心API，用于分析编程题目并生成测试用例。
    支持规则引擎和机器学习两种分析方式。
    
    请求方法:
        POST
        
    请求参数:
        JSON格式:
        {
            "problem_text": "编程题目描述",
            "test_case_count": 10,  // 可选，默认10
            "enable_ml": false      // 可选，是否启用ML增强
        }
        
    返回格式:
        JSON格式:
        {
            "success": true/false,
            "semantic_analysis": {
                "operation": "问题类型",
                "input_format": {...},
                "output_format": {...},
                "constraints": [...],
                "problem_text": "原始问题文本"
            },
            "test_cases": [
                {
                    "description": "测试用例描述",
                    "input": "输入数据",
                    "expected_output": "预期输出",
                    "type": "测试类型"
                }
            ],
            "ml_info": {
                "ml_enabled": true/false,
                "ml_prediction": "ML预测结果",
                "ml_confidence": 0.95,
                "rule_prediction": "规则预测结果",
                "rule_confidence": 0.88,
                "prediction_method": "hybrid/rule_based/ml_based"
            },
            "timestamp": "时间戳",
            "config": {...}
        }
        
    功能特性:
        - 智能问题类型识别
        - 输入输出格式分析
        - 约束条件提取
        - 多种类型测试用例生成
        - ML增强分析（可选）
        - 混合决策策略
        
    异常处理:
        - 问题描述为空
        - 分析失败
        - 系统异常
        
    访问方式:
        POST http://localhost:5000/api/analyze
    """
    try:
        # 获取请求参数
        data = request.get_json()
        problem_text = data.get('problem_text', '')
        test_case_count = data.get('test_case_count', 10)
        enable_ml = data.get('enable_ml', False)
        
        # 验证输入参数
        if not problem_text.strip():
            return jsonify({
                'success': False,
                'error': '问题描述不能为空'
            })
        
        # 调用分析器进行问题分析
        result = analyzer.analyze_problem(
            problem_text=problem_text,
            generate_test_cases=True,
            test_case_count=test_case_count
        )
        
        # 添加ML增强信息
        if enable_ml and hasattr(analyzer.semantic_analyzer, 'get_prediction_info'):
            # 获取ML预测信息
            prediction_info = analyzer.semantic_analyzer.get_prediction_info(problem_text)
            result['ml_info'] = {
                'ml_enabled': True,
                'ml_prediction': prediction_info.get('ml_prediction'),
                'ml_confidence': prediction_info.get('ml_confidence', 0.0),
                'rule_prediction': prediction_info.get('rule_prediction'),
                'rule_confidence': prediction_info.get('rule_confidence', 0.0),
                'prediction_method': prediction_info.get('prediction_method', 'rule_based')
            }
        else:
            # 仅使用规则引擎
            result['ml_info'] = {
                'ml_enabled': False,
                'prediction_method': 'rule_based'
            }
        
        # 调整数据格式以匹配前端期望
        if result['success']:
            # 提取语义分析结果和测试用例
            analysis_result = result.get('analysis_result', {})
            test_cases = analysis_result.get('test_cases', [])
            
            # 构建前端期望的数据格式
            frontend_result = {
                'success': True,
                'semantic_analysis': analysis_result,
                'test_cases': test_cases,
                'timestamp': result.get('timestamp'),
                'config': result.get('config', {})
            }
            
            return jsonify(frontend_result)
        else:
            return jsonify(result)
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'分析失败: {str(e)}'
        })

@app.route('/export', methods=['POST'])
@app.route('/api/export', methods=['POST'])
def export():
    """导出分析结果"""
    try:
        data = request.get_json()
        result = data.get('result', {})
        format_type = data.get('format', 'json')
        
        if format_type == 'json':
            content = json.dumps(result, ensure_ascii=False, indent=2)
            filename = f"analysis_result_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
            mimetype = 'application/json'
        elif format_type == 'txt':
            content = _format_result_as_text(result)
            filename = f"analysis_result_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
            mimetype = 'text/plain'
        elif format_type == 'python':
            content = _format_result_as_python(result)
            filename = f"analysis_result_{datetime.now().strftime('%Y%m%d_%H%M%S')}.py"
            mimetype = 'text/plain'
        elif format_type == 'markdown':
            content = _format_result_as_markdown(result)
            filename = f"analysis_result_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md"
            mimetype = 'text/markdown'
        else:
            return jsonify({
                'success': False,
                'error': f'不支持的导出格式: {format_type}'
            })
        
        return jsonify({
            'success': True,
            'content': content,
            'filename': filename,
            'mimetype': mimetype
        })
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'导出失败: {str(e)}'
        })

@app.route('/batch_export', methods=['POST'])
def batch_export():
    """批量导出"""
    try:
        data = request.get_json()
        results = data.get('results', [])
        
        if not results:
            return jsonify({
                'success': False,
                'error': '没有可导出的结果'
            })
        
        # 创建ZIP文件
        zip_buffer = io.BytesIO()
        with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
            for i, result in enumerate(results):
                # JSON格式
                json_content = json.dumps(result, ensure_ascii=False, indent=2)
                zip_file.writestr(f"result_{i+1}.json", json_content)
                
                # 文本格式
                txt_content = _format_result_as_text(result)
                zip_file.writestr(f"result_{i+1}.txt", txt_content)
        
        zip_buffer.seek(0)
        
        return jsonify({
            'success': True,
            'content': zip_buffer.getvalue(),
            'filename': f"batch_export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip",
            'mimetype': 'application/zip'
        })
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'批量导出失败: {str(e)}'
        })

@app.route('/history')
def get_history():
    """获取分析历史"""
    try:
        history = analyzer.get_analysis_history()
        return jsonify({
            'success': True,
            'history': history
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'获取历史失败: {str(e)}'
        })

@app.route('/clear_history', methods=['POST'])
def clear_history():
    """清空分析历史"""
    try:
        analyzer.clear_history()
        return jsonify({
            'success': True,
            'message': '历史记录已清空'
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'清空历史失败: {str(e)}'
        })

@app.route('/api/samples')
def get_samples():
    """获取示例问题"""
    samples = [
        {
            'title': '字符串字母统计',
            'description': '请编写一个函数fun(char *tt,int pp[])（无返回值）,统计在 tt 字符串中从 \'a\' 到 \'z\' 的 26 个字母各自出现的次数，并依次放在 pp 所指数组中。'
        },
        {
            'title': '阶乘计算',
            'description': 'x 的阶乘，即= x * (x-1) * (x-2) * ··· * 2 * 1。输入一个整数 m，计算并输出其阶乘的值。'
        },
        {
            'title': '三角序列',
            'description': '有一堆煤球，堆成三角棱锥形。具体：第一层放 1 个，第二层 3 个（排列成三角形），第三层 6 个（排列成三角形），第四层 10 个（排列成三角形），....如果一共有 N 层，共有多少个煤球？'
        },
        {
            'title': '字符串顺序检查',
            'description': '现在给你一个仅由字符 a 和 b 组成的字符串 s 作为输入。你需要编写一个程序来实现字符串中每个 a 都出现在每个 b 之前，如果满足要求，那我们就输出 True ；否则，我们就输出 False 。'
        },
        {
            'title': '成绩统计',
            'description': 'm 个人的成绩存放在 score 数组中，请编写函数 fun,它的功能是：将低于平均分的人数作为函数值返回，将低于平均分的人数放在 below 所指的数组中。'
        },
        {
            'title': '条件求和',
            'description': '输入一个整数 n，输出小于 n 并且能被 37 整除的所有自然数之和。没有则输出 0。'
        },
        {
            'title': '简单加法',
            'description': '计算两个数的和'
        }
    ]
    
    return jsonify({
        'success': True,
        'samples': samples
    })

@app.route('/api/statistics')
def get_statistics():
    """获取统计信息"""
    history = analyzer.get_analysis_history()
    
    total_analyses = len(history)
    successful_analyses = len([h for h in history if h.get('success', False)])
    
    operation_counts = {}
    for record in history:
        operation = record.get('operation', 'unknown')
        operation_counts[operation] = operation_counts.get(operation, 0) + 1
    
    return jsonify({
        'success': True,
        'statistics': {
            'total_analyses': total_analyses,
            'successful_analyses': successful_analyses,
            'success_rate': successful_analyses / total_analyses if total_analyses > 0 else 0,
            'operation_counts': operation_counts
        }
    })

@app.route('/api/download/<filename>')
def download_file(filename):
    """下载文件"""
    # 这里可以实现文件下载逻辑
    return jsonify({
        'success': False,
        'error': '文件下载功能暂未实现'
    })

# ==================== 教师测试用例管理功能 ====================

@app.route('/api/problems', methods=['GET'])
def get_problems():
    """获取问题列表（支持分页和搜索）"""
    try:
        # 获取查询参数
        problem_type = request.args.get('problem_type')
        created_by = request.args.get('created_by', 'teacher')
        search = request.args.get('search', '').strip()
        
        # 分页参数
        page = int(request.args.get('page', 1))
        per_page = int(request.args.get('per_page', 100))
        limit = int(request.args.get('limit', 100))
        
        # 获取问题列表
        problems = test_case_db.get_problems(
            problem_type=problem_type,
            created_by=created_by,
            search=search,
            limit=limit
        )
        
        # 为每个问题添加测试用例数量
        problems_with_counts = []
        for problem in problems:
            problem_dict = problem.__dict__
            # 获取该问题的测试用例数量
            test_cases = test_case_db.get_test_cases_by_problem(problem.id)
            problem_dict['test_case_count'] = len(test_cases)
            problems_with_counts.append(problem_dict)
        
        return jsonify({
            'success': True,
            'problems': problems_with_counts,
            'total': len(problems_with_counts)
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'获取问题列表失败: {str(e)}'
        })

@app.route('/api/test-cases', methods=['GET'])
def get_test_cases():
    """获取测试用例列表"""
    try:
        problem_id = request.args.get('problem_id')
        problem_type = request.args.get('problem_type')
        test_type = request.args.get('test_type')
        created_by = request.args.get('created_by', 'teacher')
        limit = int(request.args.get('limit', 100))
        
        # 如果指定了problem_id，则只获取该问题的测试用例
        if problem_id:
            test_cases = test_case_db.get_test_cases_by_problem(int(problem_id))
        else:
            test_cases = test_case_db.get_test_cases()
        
        # 为每个测试用例添加问题信息
        test_cases_with_problems = []
        for tc in test_cases:
            tc_dict = tc.__dict__
            # 获取该测试用例关联的问题
            problems = test_case_db.get_problems_by_test_case(tc.id)
            if problems:
                problem = problems[0]  # 取第一个问题（通常一个测试用例只关联一个问题）
                tc_dict['problem'] = {
                    'id': problem.id,
                    'description': problem.description,
                    'input_format': problem.input_format,
                    'output_format': problem.output_format
                }
            test_cases_with_problems.append(tc_dict)
        
        return jsonify({
            'success': True,
            'test_cases': test_cases_with_problems
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'获取测试用例失败: {str(e)}'
        })

@app.route('/api/test-cases', methods=['POST'])
def save_test_case():
    """保存测试用例"""
    try:
        data = request.get_json()
        
        test_case = TestCase(
            title=data.get('title', ''),
            description=data.get('description', ''),
            problem_type=data.get('problem_type', ''),
            input_data=data.get('input_data'),
            expected_output=data.get('expected_output'),
            test_type=data.get('test_type', 'normal'),
            created_by=data.get('created_by', 'teacher'),
            tags=data.get('tags', []),
            difficulty=data.get('difficulty', 'medium')
        )
        
        test_case_id = test_case_db.save_test_case(test_case)
        
        return jsonify({
            'success': True,
            'test_case_id': test_case_id,
            'message': '测试用例保存成功'
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'保存测试用例失败: {str(e)}'
        })

@app.route('/api/test-cases/<int:test_case_id>', methods=['PUT'])
def update_test_case(test_case_id):
    """更新测试用例"""
    try:
        data = request.get_json()
        
        # 获取现有测试用例
        existing_test_case = test_case_db.get_test_case(test_case_id)
        if not existing_test_case:
            return jsonify({
                'success': False,
                'error': '测试用例不存在'
            })
        
        # 更新字段
        existing_test_case.title = data.get('title', existing_test_case.title)
        existing_test_case.description = data.get('description', existing_test_case.description)
        existing_test_case.problem_type = data.get('problem_type', existing_test_case.problem_type)
        existing_test_case.input_data = data.get('input_data', existing_test_case.input_data)
        existing_test_case.expected_output = data.get('expected_output', existing_test_case.expected_output)
        existing_test_case.test_type = data.get('test_type', existing_test_case.test_type)
        existing_test_case.tags = data.get('tags', existing_test_case.tags)
        existing_test_case.difficulty = data.get('difficulty', existing_test_case.difficulty)
        existing_test_case.updated_at = datetime.now().isoformat()
        
        test_case_db.save_test_case(existing_test_case)
        
        return jsonify({
            'success': True,
            'message': '测试用例更新成功'
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'更新测试用例失败: {str(e)}'
        })

@app.route('/api/test-cases/<int:test_case_id>', methods=['DELETE'])
def delete_test_case(test_case_id):
    """删除测试用例"""
    try:
        success = test_case_db.delete_test_case(test_case_id)
        
        if success:
            return jsonify({
                'success': True,
                'message': '测试用例删除成功'
            })
        else:
            return jsonify({
                'success': False,
                'error': '测试用例不存在'
            })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'删除测试用例失败: {str(e)}'
        })

@app.route('/api/test-case-sets', methods=['GET'])
def get_test_case_sets():
    """获取测试用例集合列表"""
    try:
        problem_type = request.args.get('problem_type')
        created_by = request.args.get('created_by', 'teacher')
        
        test_case_sets = test_case_db.get_test_case_sets(
            problem_type=problem_type,
            created_by=created_by
        )
        
        return jsonify({
            'success': True,
            'test_case_sets': [test_case_set.__dict__ for test_case_set in test_case_sets]
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'获取测试用例集合失败: {str(e)}'
        })

@app.route('/api/test-case-sets', methods=['POST'])
def save_test_case_set():
    """保存测试用例集合"""
    try:
        data = request.get_json()
        
        # 创建测试用例对象
        test_cases = []
        for tc_data in data.get('test_cases', []):
            test_case = TestCase(
                title=tc_data.get('title', ''),
                description=tc_data.get('description', ''),
                problem_type=tc_data.get('problem_type', ''),
                input_data=tc_data.get('input_data'),
                expected_output=tc_data.get('expected_output'),
                test_type=tc_data.get('test_type', 'normal'),
                tags=tc_data.get('tags', []),
                difficulty=tc_data.get('difficulty', 'medium')
            )
            test_cases.append(test_case)
        
        test_case_set = TestCaseSet(
            name=data.get('name', ''),
            description=data.get('description', ''),
            problem_type=data.get('problem_type', ''),
            test_cases=test_cases,
            created_by=data.get('created_by', 'teacher'),
            tags=data.get('tags', [])
        )
        
        test_case_set_id = test_case_db.save_test_case_set(test_case_set)
        
        return jsonify({
            'success': True,
            'test_case_set_id': test_case_set_id,
            'message': '测试用例集合保存成功'
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'保存测试用例集合失败: {str(e)}'
        })

@app.route('/api/save-problem-and-test-case', methods=['POST'])
def save_problem_and_test_case():
    """保存问题和测试用例（优化版）"""
    try:
        data = request.get_json()
        problem_data = data.get('problem', {})
        test_case_data = data.get('test_case', {})
        
        # 导入数据库管理类
        from test_case_manager import test_case_db, Problem, TestCase
        
        # 创建问题对象
        problem = Problem(
            description=problem_data.get('description', ''),
            input_format=problem_data.get('input_format'),
            output_format=problem_data.get('output_format')
        )
        
        # 保存问题
        problem_id = test_case_db.save_problem(problem)
        
        # 创建测试用例对象（不包含问题信息）
        test_case = TestCase(
            title=test_case_data.get('title', ''),
            description=test_case_data.get('description', ''),
            input_data=test_case_data.get('input_data', {}),
            expected_output=test_case_data.get('expected_output', {}),
            test_type=test_case_data.get('test_type', 'normal'),
            created_by=test_case_data.get('created_by', 'teacher'),
            tags=test_case_data.get('tags', []),
            difficulty=test_case_data.get('difficulty', 'medium')
        )
        
        # 保存测试用例
        test_case_id = test_case_db.save_test_case(test_case)
        
        # 建立问题与测试用例的关联关系
        test_case_db.add_test_case_to_problem(problem_id, test_case_id)
        
        return jsonify({
            'success': True,
            'problem_id': problem_id,
            'test_case_id': test_case_id,
            'message': '问题和测试用例保存成功'
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'保存失败: {str(e)}'
        })

@app.route('/api/save-generated-test-cases', methods=['POST'])
def save_generated_test_cases():
    """保存生成的测试用例（智能分析，优化版）"""
    # 检查登录状态
    if not session.get('is_logged_in', False):
        return jsonify({
            'success': False,
            'error': '请先登录后再保存测试用例',
            'require_login': True
        })
    
    try:
        data = request.get_json()
        
        # 从分析结果中提取数据
        semantic_analysis = data.get('semantic_analysis', {})
        test_cases_data = data.get('test_cases', [])
        
        # 提取问题信息
        problem_text = semantic_analysis.get('problem_text', '')
        problem_type = semantic_analysis.get('operation', '未知类型')
        
        # 处理input_format和output_format（可能是字典或字符串）
        input_format_raw = semantic_analysis.get('input_format', '')
        if isinstance(input_format_raw, dict):
            input_format = input_format_raw.get('description', '')
        else:
            input_format = str(input_format_raw) if input_format_raw else ''
            
        output_format_raw = semantic_analysis.get('output_format', '')
        if isinstance(output_format_raw, dict):
            output_format = output_format_raw.get('description', '')
        else:
            output_format = str(output_format_raw) if output_format_raw else ''
        
        title = f'{problem_type}测试用例集合'
        
        # 导入数据库管理类
        from test_case_manager import test_case_db, Problem, TestCase
        
        # 创建问题对象
        problem = Problem(
            description=problem_text,
            input_format=input_format,
            output_format=output_format
        )
        
        # 保存问题
        problem_id = test_case_db.save_problem(problem)
        
        # 创建测试用例对象并保存到数据库
        saved_test_case_ids = []
        
        for i, tc_data in enumerate(test_cases_data):
            # 确保数据被正确序列化
            input_data = tc_data.get('input')
            expected_output = tc_data.get('expected_output')
            
            # 如果数据是复杂对象，确保它们可以被JSON序列化
            if isinstance(input_data, (dict, list)):
                input_data = json.dumps(input_data, ensure_ascii=False)
            if isinstance(expected_output, (dict, list)):
                expected_output = json.dumps(expected_output, ensure_ascii=False)
            
            test_case = TestCase(
                title=f"{title} - 测试用例{i+1}",
                description=f"自动生成的{problem_type}测试用例",
                input_data=input_data,
                expected_output=expected_output,
                test_type=tc_data.get('type', 'normal'),
                created_by=session.get('username', 'teacher'),
                tags=[problem_type, 'auto-generated']
            )
            # 保存到test_cases表
            test_case_id = test_case_db.save_test_case(test_case)
            saved_test_case_ids.append(test_case_id)
            
            # 建立问题与测试用例的关联关系
            test_case_db.add_test_case_to_problem(problem_id, test_case_id)
        
        return jsonify({
            'success': True,
            'problem_id': problem_id,
            'test_case_ids': saved_test_case_ids,
            'message': f'成功保存问题、{len(test_cases_data)}个测试用例和关联关系'
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'保存生成的测试用例失败: {str(e)}'
        })

@app.route('/api/problems/<int:problem_id>', methods=['DELETE'])
def delete_problem(problem_id):
    """删除问题"""
    try:
        success = test_case_db.delete_problem(problem_id)
        if success:
            return jsonify({
                'success': True,
                'message': '问题删除成功'
            })
        else:
            return jsonify({
                'success': False,
                'error': '问题不存在或删除失败'
            })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': f'删除问题失败: {str(e)}'
        })

# ==================== 主程序入口 ====================

if __name__ == '__main__':
    """
    主程序入口
    
    当直接运行此文件时，启动Flask Web应用服务器。
    提供智能测试用例生成系统的完整Web服务。
    
    启动配置:
        - 调试模式: debug=True
        - 主机地址: host='0.0.0.0' (允许外部访问)
        - 端口号: port=5000
        - 访问地址: http://localhost:5000
    
    系统功能:
        1. 编程题目智能分析
        2. 测试用例自动生成
        3. 用户认证和权限管理
        4. 测试用例管理
        5. 数据导出和下载
        6. 历史记录和统计
    
    技术栈:
        - 后端: Flask + Python
        - 前端: HTML + CSS + JavaScript
        - 数据库: MySQL
        - 机器学习: scikit-learn
        - 规则引擎: JSON + 正则表达式
    
    使用说明:
        1. 确保MySQL数据库已启动
        2. 运行 python web_app.py
        3. 访问 http://localhost:5000
        4. 使用系统进行编程题目分析
    
    注意事项:
        - 生产环境需要修改secret_key
        - 建议使用WSGI服务器部署
        - 确保数据库连接配置正确
    """
    print("启动智能测试用例生成系统...")
    print("访问地址: http://localhost:5000")
    app.run(debug=True, host='0.0.0.0', port=5000)